package com.lyn.io.sp

import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import com.lyn.io.sp.annotation.SpBool
import com.lyn.io.sp.annotation.SpFloat
import com.lyn.io.sp.annotation.SpInt
import com.lyn.io.sp.annotation.SpLong
import com.lyn.io.sp.annotation.SpString

/**
 * sp 实现类
 * @author longyn 2025/03/01
 * @version 1.0.0
 */
class SpImp : Sp {

    private val TAG = "SpImp"
    private lateinit var sharedPreferences: SharedPreferences
    private lateinit var defaultT: Any
    override fun initialize(context: Context, name: String) {
        sharedPreferences = context.getSharedPreferences(name, Context.MODE_PRIVATE)
    }

    override fun initialize(context: Context, name: String, defaultT: Any) {
        sharedPreferences = context.getSharedPreferences(name, Context.MODE_PRIVATE)
        this.defaultT = defaultT
    }

    override fun initialize(sharedPreferences: SharedPreferences) {
        this@SpImp.sharedPreferences = sharedPreferences
    }


    override fun initialize(sharedPreferences: SharedPreferences, defaultT: Any) {
        this@SpImp.sharedPreferences = sharedPreferences
        this.defaultT = defaultT
    }


    override fun getString(key: String): String {
        return sharedPreferences.getString(key, getStringDefaultValue(key)).toString()
    }

    override fun getString(key: String, defaultValue: String): String {
        return sharedPreferences.getString(key, defaultValue).toString()
    }

    override fun setString(key: String, value: String) {
        sharedPreferences.edit().putString(key, value).apply()
    }

    override fun getInt(key: String): Int {
        return sharedPreferences.getInt(key, getIntDefaultValue(key))
    }

    override fun getInt(key: String, defaultValue: Int): Int {
        return sharedPreferences.getInt(key, defaultValue)
    }

    override fun setInt(key: String, value: Int) {
        sharedPreferences.edit().putInt(key, value).apply()
    }

    override fun getLong(key: String): Long {
        return sharedPreferences.getLong(key, getLongDefaultValue(key))
    }

    override fun getLong(key: String, defaultValue: Long): Long {
        return sharedPreferences.getLong(key, defaultValue)
    }

    override fun setLong(key: String, value: Long) {
        sharedPreferences.edit().putLong(key, value).apply()
    }

    override fun getFloat(key: String): Float {
        return sharedPreferences.getFloat(key, getFloatDefaultValue(key))
    }

    override fun getFloat(key: String, defaultValue: Float): Float {
        return sharedPreferences.getFloat(key, defaultValue)
    }

    override fun setFloat(key: String, value: Float) {
        sharedPreferences.edit().putFloat(key, value).apply()
    }

    override fun getBoolean(key: String): Boolean {
        return sharedPreferences.getBoolean(key, getBoolDefaultValue(key))
    }

    override fun getBoolean(key: String, defaultValue: Boolean): Boolean {
        return sharedPreferences.getBoolean(key, defaultValue)
    }

    override fun setBoolean(key: String, value: Boolean) {
        sharedPreferences.edit().putBoolean(key, value).apply()
    }

    override fun clear() {
        sharedPreferences.edit().clear().apply()
    }

    private fun getStringDefaultValue(name: String): String {
        if (!this@SpImp::defaultT.isInitialized) {
            return ""
        }
        val fields = defaultT::class.java.fields
        fields.forEach { field ->
            field.isAccessible = true
            val spString = field.getAnnotation(SpString::class.java)
            if (spString != null) {
                if (name == field.get(name) as String) {
                    return spString.defaultValue
                }
            }
        }
        return ""
    }

    private fun getIntDefaultValue(name: String): Int {
        if (!this@SpImp::defaultT.isInitialized) {
            return 0
        }
        val fields = defaultT::class.java.fields
        fields.forEach { field ->
            field.isAccessible = true
            val spInt = field.getAnnotation(SpInt::class.java)
            if (spInt != null) {
                if (name == field.get(name) as String) {
                    return spInt.defaultValue
                }
            }
        }
        return 0
    }

    private fun getBoolDefaultValue(name: String): Boolean {
        if (!this@SpImp::defaultT.isInitialized) {
            return false
        }
        val fields = defaultT::class.java.fields
        fields.forEach { field ->
            field.isAccessible = true
            val spBool = field.getAnnotation(SpBool::class.java)
            if (spBool != null) {
                if (name == field.get(name) as String) {
                    return spBool.defaultValue
                }
            }
        }
        return false
    }

    private fun getLongDefaultValue(name: String): Long {
        if (!this@SpImp::defaultT.isInitialized) {
            return 0
        }
        val fields = defaultT::class.java.fields
        fields.forEach { field ->
            field.isAccessible = true
            val spLong = field.getAnnotation(SpLong::class.java)
            if (spLong != null) {
                if (name == field.get(name) as String) {
                    return spLong.defaultValue
                }
            }
        }
        return 0
    }


    private fun getFloatDefaultValue(name: String): Float {
        if (!this@SpImp::defaultT.isInitialized) {
            return 0f
        }
        val fields = defaultT::class.java.fields
        fields.forEach { field ->
            field.isAccessible = true
            val spFloat = field.getAnnotation(SpFloat::class.java)
            if (spFloat != null) {
                if (name == field.get(name) as String) {
                    return spFloat.defaultValue
                }
            }
        }
        return 0f
    }
}